Skip to content

Conversation

@theerebuss
Copy link
Contributor

@theerebuss theerebuss commented Jun 1, 2022

New Behavior

Added the selectable property which will control:

  • If we show a checkbox on the Card
  • Apply an onClick and an onKeyDown(Enter key only) event on the card element and an onChange event to the checkbox. These will all flip the selected state's value and then call the onCardSelect prop method
  • Apply Fluent styles for when card is selected

unselected selectable card

selected selectable card

Related Issue(s)

#19336

@fabricteam
Copy link
Collaborator

fabricteam commented Jun 1, 2022

📊 Bundle size report

Package & Exports Baseline (minified/GZIP) PR Change
react-card
Card - All
66.137 kB
18.69 kB
92.101 kB
24.998 kB
25.964 kB
6.308 kB
react-card
Card
61.293 kB
17.567 kB
87.498 kB
23.985 kB
26.205 kB
6.418 kB
Unchanged fixtures
Package & Exports Size (minified/GZIP)
react-card
CardFooter
7.737 kB
3.264 kB
react-card
CardHeader
9.302 kB
3.779 kB
react-card
CardPreview
7.838 kB
3.316 kB
react-components
react-components: Accordion, Button, FluentProvider, Image, Menu, Popover
185.285 kB
51.364 kB
react-components
react-components: FluentProvider & webLightTheme
33.988 kB
11.108 kB
🤖 This report was generated against a827840680beff7297d0fc27425ea20426a00de3

@size-auditor
Copy link

size-auditor bot commented Jun 1, 2022

Asset size changes

Size Auditor did not detect a change in bundle size for any component!

Baseline commit: a827840680beff7297d0fc27425ea20426a00de3 (build)

@fabricteam
Copy link
Collaborator

fabricteam commented Jun 1, 2022

Perf Analysis (@fluentui/react-components)

No significant results to display.

All results

Scenario Render type Master Ticks PR Ticks Iterations Status
Avatar mount 1363 1382 5000
Button mount 1021 1045 5000
FluentProvider mount 2285 2235 5000
FluentProviderWithTheme mount 742 753 10
FluentProviderWithTheme virtual-rerender 714 730 10
FluentProviderWithTheme virtual-rerender-with-unmount 786 755 10
MakeStyles mount 2017 2052 50000

@codesandbox-ci
Copy link

codesandbox-ci bot commented Jun 2, 2022

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 9b0e88e:

Sandbox Source
@fluentui/react 8 starter Configuration
@fluentui/react-components 9 starter Configuration

</div>
<CardFooter>
<Button id="open-button" onClick={alert} appearance="primary">
<Button id="open-button" onClick={() => console.log('open-button clicked')} appearance="primary">
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid usage of alert.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wondering what is the best practice here ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found that alert doesn't work with Cypress (on WSL at least) so I went with something more reliable. Output isn't really used for anything, so maybe we remove it?

Comment on lines -63 to -121
interactiveNoOutline: {
':hover::after': {
...shorthands.borderColor(tokens.colorTransparentStrokeInteractive),
},
':active::after': {
...shorthands.borderColor(tokens.colorTransparentStrokeInteractive),
},
},
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merged into each separate appearance style to simplify assignment logic later on.

Comment on lines -192 to -255
const interactive =
state.root.onClick ||
state.root.onMouseUp ||
state.root.onMouseDown ||
state.root.onPointerUp ||
state.root.onPointerDown ||
state.root.onTouchStart ||
state.root.onTouchEnd;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

selectable prop now controls intractability.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, this was an incorrect assumption. Card should still get interactive styles without selectable if it is "interactive". We'll need to double check what interactive means but for now we'll keep this logic.

@theerebuss theerebuss mentioned this pull request Jun 6, 2022
37 tasks
@theerebuss theerebuss marked this pull request as ready for review June 6, 2022 12:49
@theerebuss theerebuss requested a review from a team as a code owner June 6, 2022 12:49
</div>
<CardFooter>
<Button id="open-button" onClick={alert} appearance="primary">
<Button id="open-button" onClick={() => console.log('open-button clicked')} appearance="primary">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wondering what is the best practice here ?

@theerebuss theerebuss requested a review from a team as a code owner June 6, 2022 14:18
</Card>
),
{
includeRtl: true,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RTL not necessary, already tested in non-interactive test.

onClick: onChangeHandler,
onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => {
if (event.key === Enter || event.key === Space) {
event.preventDefault();
Copy link
Contributor Author

@theerebuss theerebuss Jun 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a fan at all of preventing browser defaults but, if we don't, it will otherwise collide with our interception of Spacebar usage. Open to more elegant solutions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

q: curious if we might have this funcionality somewhere else already so we can make it generic and reuse for consistency?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked the demos and run into interesting situation. is this supposed to work like following ?

image
image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a fan at all of preventing browser defaults but, if we don't, it will otherwise collide with our interception of Spacebar usage

what behaviour are you referring to, scrolling the page ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Under the focus of a checkbox, as you mentioned, Spacebar already checks it. This will check the checkbox, but the event is then bubbled up to the Card handler and it gets checked again.
I'll need some time to analyze this and find out a better approach.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also now thinking about how this will interact with the requested focus behaviors, given that Enter is supposed to "go into the card" and focus the inner elements. I guess we need to bring this up with design and clarify.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, to me that behaviour is kinda confusing as both events will trigger (selectable and action click) which also ads some lag (freezes UI for second or so - might be Storybook related though). I'd expect to not mark it as selected if I click on action control

onClick: onChangeHandler,
onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => {
if (event.key === Enter || event.key === Space) {
event.preventDefault();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

q: curious if we might have this funcionality somewhere else already so we can make it generic and reuse for consistency?

export const useCardStyles_unstable = (state: CardState): CardState => {
const styles = useStyles();

const hasInteraction =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wondering if this is what we want, enabling "magic" behaviour based on some props defined ? should we be rather explicit with our APIs ?

Copy link
Contributor Author

@theerebuss theerebuss Jun 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean having an interactive prop that would enable said styles? I'm afraid that if we want to guarantee interaction styles and we need to rely on the user knowing beforehand such a prop is required will only lead to misalignment between intended design behavior and the use case.
This would be the result:

<Card interactive onClick={() => {}}>{...}</Card>
<Card interactive selectable selected={selected} onCardSelect={() => {}}>{...}</Card>

If the user misses this, they get no cursor: pointer / styles when clicking and when selected.

Copy link
Contributor

@Hotell Hotell Jun 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant is that in current state, the API is not explicit (mainly from Types API surface perspective). Based on this logic I don't have to provide selectable only some of the event handlers you're checking for, which will turn that behaviour on.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean having an interactive prop that would enable said styles?

yes to have this explicit if possible

onClick: onChangeHandler,
onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => {
if (event.key === Enter || event.key === Space) {
event.preventDefault();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked the demos and run into interesting situation. is this supposed to work like following ?

image
image

onClick: onChangeHandler,
onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => {
if (event.key === Enter || event.key === Space) {
event.preventDefault();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a fan at all of preventing browser defaults but, if we don't, it will otherwise collide with our interception of Spacebar usage

what behaviour are you referring to, scrolling the page ?

@theerebuss theerebuss marked this pull request as draft June 7, 2022 11:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants